﻿using Architecture.Repository.Interface;
using Architeture.Domain;
using Architeture.Domain.DTO;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Security.AccessControl;
using System.Security.Claims;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;
using static Microsoft.EntityFrameworkCore.DbLoggerCategory;

namespace Architecture.Domain.Service
{
    public class UserService : IUserService
    {
        protected readonly IUserRepository userRep;
        protected readonly IProvincelRepository proRep;
        protected readonly ICityInfoRepository citRep;
        protected readonly ICountyRepository couRep;
        protected readonly IUserRoleRepository roleRep;
        protected readonly IRoleRepository role1;
        protected readonly IRoleMenuRepsitory rolemenuRep;
        protected readonly MenuIrepsitory menuRep;

        public UserService(IUserRepository userRep, IProvincelRepository proRep, ICityInfoRepository citRep, ICountyRepository couRep, IUserRoleRepository roleRep, IRoleRepository role1, IRoleMenuRepsitory rolemenuRep, MenuIrepsitory menuRep)
        {
            this.userRep = userRep;
            this.proRep = proRep;
            this.citRep = citRep;
            this.couRep = couRep;
            this.roleRep = roleRep;
            this.role1 = role1;
            this.rolemenuRep = rolemenuRep;
            this.menuRep = menuRep;
        }

        public async Task<int> AddUser(UserInfo model)
        {
            model.UserPwd = "12345678";
            model.AddTime = DateTime.Now.ToString();
            model.AddName = "张三";
            var userList = (await userRep.GetAllAsync()).Count(x => x.UserName == model.UserName);
            if (userList > 0)
            {
                return -2;
            }
            else
            {
                var result = await userRep.AddAsync(model);
                if (result > 0)
                {
                    return 1;
                }
                else
                {
                    return -1;
                }
            }
        }

        public async Task<UserPage> GetUserInfo(int pageindex, int pagesize, string? UName)
        {
            var arr = await role1.GetAllAsync();
            var role = await roleRep.GetUrlist();
            var list = (from a in await userRep.GetAll()
                        join b in await proRep.GetAllAsync() on a.ProvinceInfoId equals b.ProvinceInfoId
                        join c in await citRep.GetAllAsync() on a.CityInfoId equals c.CityInfoId
                        join d in await couRep.GetAllAsync() on a.countyId equals d.CountyInfoId
                        where a.IsDel
                        select new UserPagelist
                        {
                            UserInfoid = a.UserInfoid,
                            UserName = a.UserName,
                            Address = a.Address,
                            IsSex = a.IsSex,
                            AddName = a.AddName,
                            AddTime = a.AddTime,
                            UpdName = a.UpdName,
                            UpdTime = a.UpdTime,
                            ProvinceName = b.ProvinceName,
                            CityName = c.CityName,
                            CountyInfoName = d.CountyInfoName,
                            value = (from q in arr
                                     join w in role on q.RoleInfoid equals w.RoleInfoid
                                     where w.UserInfoid == a.UserInfoid
                                     select new Rname
                                     {
                                         RName = q.RName
                                     }).ToList()
                        }).ToList();
            if (!string.IsNullOrEmpty(UName))
            {
                list = list.Where(x => x.UserName.Contains(UName)).ToList();
            }
            var size = (pageindex - 1) * pagesize;
            var pagecount = list.Count();
            var totulcount = (int)Math.Ceiling(pagecount * 1.0 / pagesize);
            list = list.OrderByDescending(x => x.AddTime).Skip(size).Take(pagesize).ToList();
            var page = new UserPage();
            page.pagecount = pagecount;
            page.totalcount = totulcount;
            page.list = list;
            return page;
        }

        public async Task<List<mentumn>> GetUserTree(string bid)
        {
            var list = (await userRep.GetAll()).Where(x => bid.Contains(x.department.ToString())).Select(x => new mentumn
            {
                value = x.UserInfoid,
                label = x.UserName,
            });
            return list.ToList();
        }

        public Task<UserInfo> SetUserInfo(int uid)
        {
            var list = userRep.SetUser(uid);
            return list;
        }

        public async Task<int> UserDel(int uid)
        {
            var list = (await userRep.GetAll()).FirstOrDefault(x => x.UserInfoid == uid);
            if (list != null)
            {
                list.IsDel = false;
                await userRep.UserUpd(list);
                return 1;
            }
            else
            {
                return -1;
            }
        }

        public async Task<int> UserUp(UserInfo model)
        {
            model.UpdTime = DateTime.Now.ToString();
            await userRep.Update(model);
            return 1;
        }

        public async Task<int> UserRoleAdd(UserRoleInfo a)
        {
            var list = (await roleRep.GetAllAsync()).Count(x => x.UserInfoid == a.UserInfoid && x.RoleInfoid == a.RoleInfoid);
            if (list > 0)
            {
                return -1;
            }
            else
            {
                return await roleRep.AddAsync(a);
            }

        }

        public async Task<List<UserRoleChed>> GetUserRoleched(int id)
        {
            var list = (from a in await userRep.GetAllAsync()
                        join b in await roleRep.GetAllAsync() on a.UserInfoid equals b.UserInfoid
                        where b.RoleInfoid == id && !b.isDel
                        select new UserRoleChed
                        {
                            department = a.department,
                            UserInfoid = a.UserInfoid
                        }).Distinct();
            return list.ToList();
        }

        public async Task<List<ByUserInfo>> GetUerInfoBybid(int id)
        {
            var list = (from a in await userRep.GetAllAsync()
                        join b in await roleRep.GetAllAsync() on a.UserInfoid equals b.UserInfoid
                        where b.RoleInfoid == id && !b.isDel
                        select new ByUserInfo
                        {
                            UserRoleInfoid = b.UserRoleInfoid,
                            UserInfoid = b.UserInfoid,
                            UserName = a.UserName
                        }).ToList();
            return list;
        }

        public async Task<int> UserRoleDel(int id)
        {
            var list = (await roleRep.GetAllAsync()).FirstOrDefault(x => x.UserRoleInfoid == id);
            if (list != null)
            {
                list.isDel = true;
                await roleRep.Update(list);
                return 1;
            }
            else
            {
                return -1;
            }
        }

        public async Task<int> UserRoleAddNew(int rid, List<int> uid)
        {
            var list = 0;
            foreach (var item in uid)
            {
                var arrs = (await roleRep.GetAllAsync()).Count(x => x.RoleInfoid == rid && x.UserInfoid == item);
                if (arrs > 0)
                {
                    list = 0;
                }
                else
                {
                    var arr = new UserRoleInfo();
                    arr.UserInfoid = item;
                    arr.RoleInfoid = rid;
                    await roleRep.UserRoleAdd(arr);
                    list = 1;
                }

            }
            return list;
        }

        public async Task<UserLoginRealust> UserLogin(string name, string pwd)
        {
            var arr = new UserLoginRealust();
            var list = (await userRep.GetAllAsync()).FirstOrDefault(x => x.UserName == name);
            var ridlist = (from a in await roleRep.GetAllAsync()
                           where list.UserInfoid == a.UserInfoid
                           select new
                           {
                               a.RoleInfoid
                           });
            if (list != null)
            {
                if (list.UserPwd == pwd)
                {
                    //登录成功
                    arr.code = 1;
                    arr.id = list.UserInfoid;
                    var newlist = new List<int>();
                    foreach (var item in ridlist)
                    {
                        newlist.Add(item.RoleInfoid);
                    }
                    arr.rid = string.Join(',', newlist);
                }
                else
                {
                    //密码错误
                    arr.code = 2;
                }
            }
            else
            {
                //用户不存在
                arr.code = 3;
            }
            return arr;
        }

        public async Task<List<SetUserInfo>> GetUserJwt(int id)
        {
            var arr = await userRep.GetAllAsync();
            var newlist = from a in arr
                          where a.UserInfoid == id
                          select new SetUserInfo
                          {
                              UserName = a.UserName,
                              department = a.department,
                              value = arr.Where(x => x.department == a.department && x.IsBoos == true).Select(x => new userSet
                              {
                                  UserNames = x.UserName
                              }).ToList()
                          };
            return newlist.ToList();
        }

        public async Task<List<MenuSetDto>> GetUserMenuJwt(int id)
        {
            var list = (from a in await userRep.GetAllAsync()
                        join b in await roleRep.GetAllAsync() on a.UserInfoid equals b.UserInfoid
                        join c in await rolemenuRep.GetAllAsync() on b.RoleInfoid equals c.RoleInfoid
                        join d in await menuRep.GetAllAsync() on c.MenuInfoid equals d.MenuInfoid
                        where a.UserInfoid == id && d.Url != "/"
                        select new MenuSetDto
                        {
                            UserName = a.UserName,
                            MenuInfoName = d.MenuInfoName,
                            Url = d.Url,
                            IsBoos = a.IsBoos
                        }).Distinct();
            return list.ToList();
        }
    }
}

